Applying Operators and Expressions in Kotlin
Course: Android App Development
Topic: Applying Operators and Expressions
Course Link: Android App Development Course
Demo Link: Register for a Course Demo
JustAcademy Homepage: Visit JustAcademy
1. Introduction to Operators and Expressions
Operators and expressions are fundamental concepts in Kotlin programming. Operators perform operations on values and variables, while expressions combine values, variables, function calls, and operators to produce a result.
In Android development, operators and expressions are used to calculate prices, validate form inputs, check login conditions, control application behavior, compare values, update counters, and determine which screen or message should be displayed.
Kotlin supports arithmetic, comparison, logical, assignment, increment and decrement, range, membership, type-checking, and null-handling operators.
Example
fun main() {
val price = 500
val quantity = 3
val total = price * quantity
println("Total price: $total")
}
Output:
Total price: 1500
In this example, the multiplication operator (*) calculates the total price. The expression price * quantity produces a value that is stored in the total variable.
2. What Is an Operator?
An operator is a symbol or keyword that performs an operation on one or more operands. An operand is the value or variable on which the operator operates.
Example
val a = 10
val b = 5
val result = a + b
In this example:
+ is the arithmetic operator.
a and b are operands.
a + b is an expression.
result stores the value 15.
Types of Operators Based on Operands
| Type |
Description |
Example |
| Unary operator |
Operates on one operand. |
-number |
| Binary operator |
Operates on two operands. |
a + b |
| Ternary-style conditional |
Kotlin does not have Java's condition ? a : b ternary operator. Use an if expression instead. |
if (age >= 18) "Adult" else "Minor" |
3. What Is an Expression?
An expression is a combination of values, variables, operators, or function calls that produces a result. Kotlin allows many control structures, including if and when, to be used as expressions.
Example 1: Arithmetic Expression
val result = 10 + 20 * 2
println(result)
Output:
50
Multiplication has higher precedence than addition, so Kotlin calculates 20 * 2 first and then adds 10.
Example 2: Conditional Expression
val age = 21
val status = if (age >= 18) "Eligible" else "Not eligible"
println(status)
Output:
Eligible
The if expression returns one of two values, depending on the condition.
Expression vs. Statement
| Expression |
Statement |
| Produces a value that can be used in another expression or assignment. |
Performs an action in the program. |
Example: val sum = a + b |
Example: println(sum) |
Kotlin's if can return a value. |
A statement may execute an action without returning a useful value. |
4. Arithmetic Operators
Arithmetic operators perform mathematical calculations on numeric values. They are commonly used for totals, discounts, quantities, scores, progress calculations, and other application logic.
| Operator |
Name |
Example |
Result |
+ |
Addition |
10 + 5 |
15 |
- |
Subtraction |
10 - 5 |
5 |
* |
Multiplication |
10 * 5 |
50 |
/ |
Division |
10 / 5 |
2 |
% |
Remainder |
10 % 3 |
1 |
Example: Arithmetic Calculations
fun main() {
val a = 20
val b = 6
println("Addition: ${a + b}")
println("Subtraction: ${a - b}")
println("Multiplication: ${a * b}")
println("Division: ${a / b}")
println("Remainder: ${a % b}")
}
Output:
Addition: 26
Subtraction: 14
Multiplication: 120
Division: 3
Remainder: 2
Important: Integer Division
When both operands are integers, division returns an integer result, discarding the fractional part.
val result = 7 / 2
println(result) // 3
val decimalResult = 7.0 / 2
println(decimalResult) // 3.5
Use an appropriate floating-point type when the fractional part matters, such as calculating measurements or percentages. For financial calculations, consider using BigDecimal or another suitable decimal strategy when exact decimal arithmetic is required.
Understanding the Remainder Operator
The remainder operator (%) returns the remainder after division. It is useful for checking whether a number is even or odd and for repeating patterns.
val number = 14
if (number % 2 == 0) {
println("Even number")
} else {
println("Odd number")
}
Output:
Even number
5. Assignment Operators
Assignment operators store values in variables or update an existing mutable variable. Kotlin uses = for basic assignment and provides compound assignment operators for common calculations.
| Operator |
Meaning |
Example |
Equivalent calculation |
= |
Assign a value |
x = 10 |
Assign 10 to x |
+= |
Add and assign |
x += 5 |
x = x + 5 |
-= |
Subtract and assign |
x -= 2 |
x = x - 2 |
*= |
Multiply and assign |
x *= 3 |
x = x * 3 |
/= |
Divide and assign |
x /= 2 |
x = x / 2 |
%= |
Remainder and assign |
x %= 4 |
x = x % 4 |
Example
fun main() {
var score = 50
score += 10
println(score)
score -= 5
println(score)
score *= 2
println(score)
score /= 5
println(score)
}
Output:
60
55
110
22
Important: A variable declared with val cannot be reassigned. Use var when the variable itself must change. Compound assignment behavior can depend on the type and available operator functions.
6. Increment and Decrement Operators
Increment and decrement operators increase or decrease a mutable numeric variable by one.
++ increases a value by one.
-- decreases a value by one.
Prefix and Postfix Increment
The difference between prefix and postfix forms matters when the expression's result is used.
var count = 5
val first = ++count
println("First: $first")
println("Count: $count")
val second = count++
println("Second: $second")
println("Count: $count")
Output:
First: 6
Count: 6
Second: 6
Count: 7
With prefix increment, the variable is incremented before the expression returns its value. With postfix increment, the expression returns the original value before the variable is incremented.
Example: Tracking Items
var cartItems = 0
cartItems++
cartItems++
cartItems++
println("Items in cart: $cartItems")
Output:
Items in cart: 3
7. Comparison Operators
Comparison operators compare two values and return a Boolean result: true or false. They are often used in validation, conditions, filtering, and application rules.
| Operator |
Meaning |
Example |
Result |
== |
Equal in value |
5 == 5 |
true |
!= |
Not equal in value |
5 != 3 |
true |
> |
Greater than |
8 > 4 |
true |
< |
Less than |
2 < 7 |
true |
>= |
Greater than or equal to |
5 >= 5 |
true |
<= |
Less than or equal to |
3 <= 2 |
false |
Example: Age Validation
val age = 20
println(age >= 18) // true
println(age < 18) // false
println(age == 20) // true
println(age != 20) // false
Value Equality vs. Reference Equality
Kotlin distinguishes between checking whether two values are equal and checking whether two references point to the same object.
== checks structural or value equality by using equality semantics.
!= checks whether values are not equal.
=== checks referential equality for objects.
!== checks whether references are different.
val firstName = "Kotlin"
val secondName = "Kotlin"
println(firstName == secondName) // true
The example checks value equality. Do not use === when your intention is simply to compare the contents of strings or data objects.
8. Logical Operators
Logical operators combine or reverse Boolean conditions. They are particularly useful for form validation, authentication checks, access rules, and deciding whether an action should be performed.
| Operator |
Name |
Meaning |
&& |
Logical AND |
True only when both conditions are true. |
|| |
Logical OR |
True when at least one condition is true. |
! |
Logical NOT |
Reverses a Boolean value. |
Example: Login Validation
val usernameEntered = true
val passwordEntered = true
val canSubmit = usernameEntered && passwordEntered
if (canSubmit) {
println("Login form can be submitted")
} else {
println("Complete all required fields")
}
Output:
Login form can be submitted
Example: Multiple Conditions
val isAdmin = false
val isOwner = true
if (isAdmin || isOwner) {
println("Access granted")
} else {
println("Access denied")
}
Output:
Access granted
Short-Circuit Evaluation
Kotlin's && and || operators use short-circuit evaluation. The second condition is evaluated only when it is needed to determine the result.
val name: String? = null
if (name != null && name.isNotEmpty()) {
println("Name is available")
} else {
println("Name is missing")
}
Because the first condition is false, Kotlin does not evaluate name.isNotEmpty(). This prevents an attempt to access the nullable value when it is null.
9. Operator Precedence and Parentheses
Operator precedence determines which operation is evaluated first when an expression contains multiple operators. Parentheses can make the intended calculation explicit and improve readability.
Example Without Parentheses
val result = 10 + 5 * 2
println(result)
Output:
20
Multiplication is performed before addition.
Example With Parentheses
val result = (10 + 5) * 2
println(result)
Output:
30
Parentheses force the addition to be evaluated first.
General Precedence Guide
| General Priority |
Operator Examples |
Purpose |
| High |
Parentheses and member access such as object.name |
Grouping and accessing values |
| High |
Unary operators such as !x, -x, ++x |
Unary operations |
| High |
*, /, % |
Multiplication, division, remainder |
| Medium |
+, - |
Addition and subtraction |
| Medium |
<, >, <=, >=, in, is |
Comparison and membership checks |
| Lower |
==, != |
Equality checks |
| Lower |
&& |
Logical AND |
| Lower |
|| |
Logical OR |
This is a simplified guide rather than a complete precedence specification. When an expression is complex, use parentheses and consult the Kotlin language reference rather than relying on memory.
10. Range Operators
Kotlin provides range operators for representing sequences or intervals of values. They are useful in loops, validation, and checking whether a value falls within a permitted range.
.. creates a range that includes both endpoints.
.. is not the correct literal spelling; Kotlin's exclusive-end range operator is ..<, which excludes the upper endpoint.
downTo creates a descending range.
step controls the increment between range elements.
Inclusive Range Example
for (number in 1..5) {
println(number)
}
Output:
1
2
3
4
5
Exclusive Upper Bound
for (number in 1..<5) {
println(number)
}
Output:
1
2
3
4
Descending Range
for (number in 5 downTo 1) {
println(number)
}
Output:
5
4
3
2
1
Checking a Value Within a Range
val score = 85
if (score in 0..100) {
println("Valid score")
} else {
println("Invalid score")
}
Range checks are useful for verifying values such as marks, percentages, age limits, and user-selected quantities.
11. Membership Operators: in and !in
The in and !in operators check whether a value belongs to a range, collection, or another type that supports membership checking.
in returns true when the value is present or within the range.
!in returns true when the value is absent or outside the range.
Example With a List
val supportedLanguages = listOf("Kotlin", "Java", "Python")
println("Kotlin" in supportedLanguages)
println("Ruby" !in supportedLanguages)
Output:
true
true
Example: Checking a Valid Menu Option
val selectedOption = 2
if (selectedOption in 1..4) {
println("Valid menu option")
} else {
println("Invalid menu option")
}
12. Type-Checking Operators: is and !is
Kotlin provides is and !is to determine whether a value is compatible with a particular type at runtime.
is checks whether a value is of a specified type.
!is checks whether a value is not of that type.
Example
fun describe(value: Any) {
if (value is String) {
println("String length: ${value.length}")
} else if (value !is Int) {
println("Value is neither a String nor an Int")
} else {
println("Integer value: $value")
}
}
fun main() {
describe("Android")
describe(100)
describe(3.14)
}
Output:
String length: 7
Integer value: 100
Value is neither a String nor an Int
Kotlin supports smart casts in many type-checking scenarios. After a successful type check, the compiler can allow access to members of the more specific type when the value is safely known to have that type.
13. Type-Casting Operators: as and as?
Type casting converts a reference to a more specific or different compatible type when possible. Kotlin offers a regular cast and a safe cast.
| Operator |
Behavior |
as |
Performs a cast. An incompatible cast can throw a runtime exception. |
as? |
Performs a safe cast and returns null if the cast is unsuccessful. |
Example: Safe Casting
val value: Any = "Kotlin"
val text = value as? String
println(text)
Output:
Kotlin
Example: Failed Safe Cast
val value: Any = 100
val text = value as? String
println(text)
Output:
null
Safe casts are useful when working with values whose actual type may differ from what the program expects. Prefer checking the type or using as? where failure is possible instead of performing an unsafe cast without validation.
14. Null-Safety Operators
Kotlin's null-safety system helps prevent many common null-reference errors. Nullable types explicitly allow a value to be null, while non-nullable types do not.
Nullable and Non-Nullable Variables
val name: String = "Android"
val middleName: String? = null
The question mark after String indicates that middleName can hold null.
Safe-Call Operator: ?.
The safe-call operator accesses a property or calls a function only when the receiver is not null. Otherwise, the result is null.
val name: String? = null
val length = name?.length
println(length)
Output:
null
Elvis Operator: ?:
The Elvis operator provides a fallback value when the expression on its left is null.
val username: String? = null
val displayName = username ?: "Guest"
println(displayName)
Output:
Guest
Not-Null Assertion: !!
The not-null assertion operator tells Kotlin to treat a nullable expression as non-null. If the value is null at runtime, it throws a null-pointer exception.
val name: String? = "Android"
println(name!!.length)
Output:
7
Although !! can be useful in limited situations, overusing it can make applications crash. Prefer safe calls, the Elvis operator, or explicit validation when possible.
15. String Expressions and Interpolation
Kotlin supports string templates, allowing variables and expressions to be inserted into strings using the dollar sign ($).
Variable Interpolation
val appName = "My Android App"
println("Welcome to $appName")
Output:
Welcome to My Android App
Expression Interpolation
val price = 200
val quantity = 4
println("Total: ${price * quantity}")
Output:
Total: 800
String templates are useful when displaying user information, creating diagnostic messages, and formatting simple text output. For currency and localized user-facing numbers, use suitable formatting methods rather than relying on raw numeric conversion.
16. Applying Operators in Android Development
Operators are commonly used in Android app logic, including event handlers, ViewModels, form validation, and calculations.
Example 1: Calculating a Shopping Cart Total
fun calculateTotal(price: Double, quantity: Int): Double {
return price * quantity
}
fun main() {
val total = calculateTotal(249.99, 3)
println("Cart total: $total")
}
This example demonstrates multiplication in a reusable function. For production financial calculations, consider decimal arithmetic and explicit currency rounding rules.
Example 2: Validating a Registration Form
fun canRegister(
name: String,
age: Int,
acceptedTerms: Boolean
): Boolean {
return name.isNotBlank() &&
age >= 18 &&
acceptedTerms
}
fun main() {
println(canRegister("Aarav", 22, true))
}
Output:
true
The function uses logical AND and comparison operators to ensure that all required conditions are satisfied.
Example 3: Calculating a Progress Percentage
fun calculateProgress(completed: Int, total: Int): Int {
if (total <= 0) return 0
return (completed.coerceIn(0, total) * 100) / total
}
fun main() {
println(calculateProgress(3, 4))
}
Output:
75
This example checks that the total is positive and limits the completed count to the valid range. Since integer division is used, the returned percentage is an integer.
Example 4: Updating a Counter in an Android Activity
var clickCount = 0
fun onButtonClicked() {
clickCount++
println("Button clicked $clickCount times")
}
This simplified example shows the increment operator. In a real Android interface, connect a button's click listener to the appropriate application logic and expose state using the approach suitable for your UI framework.
17. Common Mistakes When Using Operators
| Mistake |
Why It Is a Problem |
Correct Approach |
Using = instead of == in a comparison |
Assignment and equality checking are different operations. |
Use == when comparing values. |
| Expecting integer division to return decimals |
Integer division discards the fractional part. |
Use a floating-point type when fractional precision is needed. |
Using !! without validating a nullable value |
A null value causes a runtime exception. |
Prefer ?., ?:, or explicit validation. |
Confusing == with === |
One checks value equality, while the other checks reference identity. |
Choose the operator based on the comparison required. |
| Ignoring operator precedence |
The expression may calculate a different result than intended. |
Use parentheses for clarity. |
Incrementing a val variable |
A read-only variable cannot be reassigned. |
Use var if the variable itself needs to change. |
| Dividing by zero |
Integer division by zero throws an arithmetic exception. |
Validate the divisor before performing division. |
| Using floating-point values for exact financial totals without a strategy |
Binary floating-point arithmetic can introduce rounding differences. |
Use decimal arithmetic and define appropriate rounding rules. |
Using & or | for Boolean conditions |
Kotlin uses && and || for logical conjunction and disjunction. |
Use the proper logical operators. |
18. Best Practices for Operators and Expressions
- Choose operators that clearly communicate the intended operation.
- Use parentheses when an expression contains several operators or could be misunderstood.
- Prefer meaningful variable names instead of complex inline calculations.
- Use Kotlin's null-safety features instead of relying on repeated not-null assertions.
- Validate user input before performing calculations.
- Check divisors before division.
- Use suitable numeric types for calculations involving fractions or money.
- Break complex conditions into named Boolean variables or small functions.
- Use short-circuit operators appropriately to avoid evaluating unnecessary conditions.
- Write unit tests for important business rules and calculations.
- Use type checks and safe casts when values can have different runtime types.
19. Practical Exercises
Exercise 1: Basic Arithmetic
Create two integer variables and print their sum, difference, product, quotient, and remainder.
Exercise 2: Even or Odd
Write a program that checks whether a given number is even or odd using the remainder operator.
Exercise 3: Eligibility Check
Create a function that returns true if a person is at least 18 years old and has accepted the required terms.
Exercise 4: Range Validation
Check whether a score is within the range of 0 to 100 using the in operator.
Exercise 5: Null-Safe Display Name
Create a nullable username and use the Elvis operator to display Guest when no username is provided.
Exercise 6: Shopping Cart
Calculate the total price of multiple items, apply a discount, and display the final amount. Consider decimal precision and rounding.
Exercise 7: Registration Validation
Combine logical and comparison operators to validate a name, email field, age, and terms acceptance.
Exercise 8: Increment and Decrement
Write a program that demonstrates the difference between prefix and postfix increment and decrement operators.
20. Mini Project: Student Result Calculator
Create a simple Kotlin program that calculates a student's total marks, percentage, and pass/fail result. This exercise combines arithmetic, comparison, logical, and conditional expressions.
Requirements
- Store marks for three subjects.
- Calculate total marks and percentage.
- Check that each mark is within the valid range.
- Display whether the student passed or failed based on the chosen pass-mark rule.
- Display the result using string interpolation.
Sample Solution
fun main() {
val math = 80
val science = 75
val english = 90
val validMarks =
math in 0..100 &&
science in 0..100 &&
english in 0..100
if (!validMarks) {
println("Invalid marks entered")
return
}
val total = math + science + english
val percentage = total / 3.0
val passed =
math >= 35 &&
science >= 35 &&
english >= 35
println("Total marks: $total / 300")
println("Percentage: $percentage%")
println("Result: ${if (passed) "Pass" else "Fail"}")
}
Expected output:
Total marks: 245 / 300
Percentage: 81.66666666666667%
Result: Pass
This mini project demonstrates arithmetic operations, membership checks, logical conditions, comparison operators, conditional expressions, and string interpolation. In a production application, format the percentage to a suitable number of decimal places.
21. Interview Questions and Answers
Q1. What is an operator in Kotlin?
Answer: An operator is a symbol or keyword that performs an operation on one or more operands, such as addition, comparison, or logical evaluation.
Q2. What is an expression?
Answer: An expression is a combination of values, variables, operators, or function calls that produces a result.
Q3. What is the difference between == and ===?
Answer: == checks value equality, while === checks whether two references point to the same object.
Q4. What is the difference between && and ||?
Answer: && returns true when both conditions are true. || returns true when at least one condition is true. Both support short-circuit evaluation.
Q5. What does the remainder operator do?
Answer: The % operator returns the remainder after division. It is commonly used to check whether a number is even or odd.
Q6. What is the difference between prefix and postfix increment?
Answer: Prefix increment changes the variable before returning the expression's value. Postfix increment returns the original value before changing the variable.
Q7. How does integer division work in Kotlin?
Answer: When both operands are integers, division produces an integer result and discards the fractional part. Use floating-point arithmetic when a fractional result is needed.
Q8. What is the Elvis operator?
Answer: The ?: operator supplies a fallback value when the expression on its left is null.
Q9. What is the difference between as and as??
Answer: as performs a cast that can fail with a runtime exception. as? performs a safe cast and returns null if the conversion is unsuccessful.
Q10. What are range operators used for?
Answer: Range operators represent intervals of values and are useful in loops, validation, and membership checks.
Q11. Why should developers avoid overusing !!?
Answer: If a nullable value is null, !! throws a runtime exception. Safer alternatives include safe calls, the Elvis operator, and explicit validation.
Q12. Can if return a value in Kotlin?
Answer: Yes. Kotlin supports if as an expression, so its branches can return values that are assigned to a variable.
22. Quick Revision Checklist
- Understand the difference between operators, operands, and expressions.
- Practice arithmetic and assignment operators.
- Understand prefix and postfix increment and decrement.
- Use comparison and logical operators to build conditions.
- Understand operator precedence and the role of parentheses.
- Practice inclusive and exclusive ranges.
- Use
in and !in for membership checks.
- Use
is and !is for type checking.
- Understand regular and safe casts.
- Apply null-safety operators such as
?., ?:, and !! appropriately.
- Use string templates to display values and expressions.
- Test important calculations and validation rules.
23. Official Learning Resources
Conclusion
Operators and expressions are essential for writing clear and reliable Kotlin code. Arithmetic operators perform calculations, comparison and logical operators evaluate conditions, assignment operators update variables, and range and null-safety operators help solve common programming problems.
By practising these concepts with Kotlin examples and Android-related scenarios, learners can build stronger application logic, validate user input, calculate values correctly, and handle nullable data safely.
Explore the JustAcademy Android App Development Course, visit the JustAcademy homepage, or register for a course demo to continue learning.